package online.misscl.lsy.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import online.misscl.lsy.entity.HospitalInformation;
import online.misscl.lsy.entity.VaccineAppointment;
import online.misscl.lsy.entity.VaccineInformation;
import online.misscl.lsy.entity.VaccineNum;
import online.misscl.lsy.entity.dto.*;
import online.misscl.lsy.entity.dto.vo.VaccineAppointmentBackVo;
import online.misscl.lsy.entity.dto.vo.VaccineAppointmentVo;
import online.misscl.lsy.mapper.*;
import online.misscl.lsy.service.VaccineAppointmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import online.misscl.lsy.util.QRCodeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 预约订单表 服务实现类
 * </p>
 *
 * @author misscl
 * @since 2023/03/11 11:14
 */
@Service
public class VaccineAppointmentServiceImpl extends ServiceImpl<VaccineAppointmentMapper, VaccineAppointment> implements VaccineAppointmentService {

    @Autowired
    private VaccineInformationMapper vaccineInformationMapper;

    @Autowired
    private VaccineUserMapper vaccineUserMapper;

//    @Autowired
//    private HospitalInformationMapper hospitalInformationMapper;
    @Autowired
    private VaccineNumMapper vaccineNumMapper;

    @Value("${linux.upload-file-path}")
    String linuxUploadFilePath;

    @Value("${windows.upload-file-path}")
    String windowsUploadFilePath;
    @Override
    public List<VaccineAppointmentBackVo> queryAppointment(VaccineAppointmentQueryDto dto) {
        MPJLambdaWrapper<VaccineAppointment> mpjLambdaWrapper = new MPJLambdaWrapper<VaccineAppointment>();
        mpjLambdaWrapper.select(VaccineAppointment::getOrderId,VaccineAppointment::getAppointmentTime
        ,VaccineAppointment::getInoculationPerson,VaccineAppointment::getVaccinePrice
        ,VaccineAppointment::getHospitalId,VaccineAppointment::getAppointmentCode
        ,VaccineAppointment::getPhone,VaccineAppointment::getVaccineId,VaccineAppointment::getCreateTime
        ,VaccineAppointment::getCreateBy,VaccineAppointment::getState)
        .leftJoin(HospitalInformation.class,HospitalInformation::getHospitalId,VaccineAppointment::getHospitalId)
        .select(HospitalInformation::getHospitalName)
         .leftJoin(VaccineInformation.class,VaccineInformation::getVaccineId,VaccineAppointment::getVaccineId)
         .select(VaccineInformation::getVaccineName)
        .like(dto.getHospitalName()!=null,HospitalInformation::getHospitalName,dto.getHospitalName())
        .like(dto.getInoculationName()!=null,VaccineAppointment::getInoculationPerson,dto.getInoculationName())
        .like(dto.getPhone()!=null,VaccineAppointment::getPhone,dto.getPhone())
        .like(dto.getCancelCause()!=null,VaccineAppointment::getCancelCause,dto.getCancelCause())
        .like(dto.getVaccineName()!=null,VaccineInformation::getVaccineName,dto.getVaccineName())
        .ge(dto.getAppointmentStartTime()!=null,VaccineAppointment::getAppointmentTime,dto.getAppointmentStartTime())
        .le(dto.getAppointmentEndTime()!=null,VaccineAppointment::getAppointmentTime,dto.getAppointmentEndTime())
        .ge(dto.getMinPrice()!=null,VaccineAppointment::getVaccinePrice,dto.getMinPrice())
        .le(dto.getMaxPrice()!=null,VaccineAppointment::getVaccinePrice,dto.getMaxPrice())
        .ge(dto.getStartTime()!=null,VaccineAppointment::getCreateTime,dto.getStartTime())
        .le(dto.getEndTime()!=null,VaccineAppointment::getCreateTime,dto.getEndTime())
        .eq(dto.getState()!=null,VaccineAppointment::getState,dto.getState())
        ;
        return baseMapper.selectJoinList(VaccineAppointmentBackVo.class,mpjLambdaWrapper);

//        return null;
    }

    @Override
    public int addAppointment(AddVaccineAppointmentDTO addVaccineAppointmentDTO, Integer userId) {
        VaccineAppointment vaccineAppointment = new VaccineAppointment();
        BeanUtils.copyProperties(addVaccineAppointmentDTO,vaccineAppointment);
        vaccineAppointment.setAppointmentTime(DateUtil.parse(addVaccineAppointmentDTO.getAppointmentTime()));
        vaccineAppointment.setAppointmentUserId(userId);
        vaccineAppointment.setVaccinePrice(vaccineInformationMapper.selectById(addVaccineAppointmentDTO.getVaccineId()).getVaccinePrice());
        vaccineAppointment.setCreateBy(vaccineUserMapper.selectById(userId).getName());
        vaccineAppointment.setState("0");
        baseMapper.insert(vaccineAppointment);

        String path = "";
        String destPath = "";
        String os = System.getProperty("os.name");
        if (os != null && os.toLowerCase().startsWith("windows")) {
            path = windowsUploadFilePath;
            destPath =  path + "\\\\" + vaccineAppointment.getOrderId() +".jpg";
        } else if (os != null && os.toLowerCase().startsWith("linux")) {
            path = linuxUploadFilePath;
            destPath =  path + vaccineAppointment.getOrderId() +".jpg";
        }

        //判断文件夹是否存在，存在就不需要重新创建，不存在就创建
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }

//        String hospitalImg = hospitalInformationMapper.selectById(addVaccineAppointmentDTO.getHospitalId()).getHospitalImg();
        try {
            //二维码存医院信息
            String appointmentInfo = JSON.toJSONString(vaccineAppointment);
            //生成二维码 预约码 todo 医院图片暂时不嵌入
            QRCodeUtil.encode(appointmentInfo, "", destPath, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        vaccineAppointment.setAppointmentCode("/img/"+vaccineAppointment.getOrderId() +".jpg");

        //扣库存
        LambdaQueryWrapper<VaccineNum> vaccineNumLambdaQueryWrapper = new LambdaQueryWrapper<>();
        vaccineNumLambdaQueryWrapper.eq(VaccineNum::getVaccineId,addVaccineAppointmentDTO.getVaccineId());
        VaccineNum vaccineNum = vaccineNumMapper.selectOne(vaccineNumLambdaQueryWrapper);
        vaccineNum.setVaccineNum(vaccineNum.getVaccineNum() - 1);
        vaccineNum.setVaccineFreezeNum(vaccineNum.getVaccineNum() + 1);
        vaccineNumMapper.updateById(vaccineNum);
        return baseMapper.updateById(vaccineAppointment);
    }

    @Override
    public int cancelAppointment(CancelAppointmentDTO cancelAppointmentDTO, Integer userId) {
        VaccineAppointment vaccineAppointment = baseMapper.selectById(cancelAppointmentDTO.getOrderId());
        vaccineAppointment.setCancelCause(cancelAppointmentDTO.getCancelCause());
        vaccineAppointment.setUpdateBy(vaccineUserMapper.selectById(userId).getName());
        vaccineAppointment.setState("1");
        return baseMapper.updateById(vaccineAppointment);
    }

    @Override
    public List<VaccineAppointmentVo> myAppointment(MyAppointmentDto myAppointmentDto, Integer userId) {
        MPJLambdaWrapper<VaccineAppointment> vaccineAppointmentMPJLambdaWrapper = new MPJLambdaWrapper<>();
        vaccineAppointmentMPJLambdaWrapper.select(VaccineAppointment::getOrderId,VaccineAppointment::getAppointmentTime,
                VaccineAppointment::getInoculationPerson,VaccineAppointment::getVaccinePrice,VaccineAppointment::getHospitalId,VaccineAppointment::getAppointmentCode,
                VaccineAppointment::getVaccineId,VaccineAppointment::getCancelCause,VaccineAppointment::getCreateTime,VaccineAppointment::getCreateBy,VaccineAppointment::getPhone,VaccineAppointment::getState)
                .leftJoin(VaccineInformation.class,VaccineInformation::getVaccineId,VaccineAppointment::getVaccineId)
                .select(VaccineInformation::getVaccineName)
                .leftJoin(HospitalInformation.class,HospitalInformation::getHospitalId,VaccineAppointment::getHospitalId)
                .select(HospitalInformation::getHospitalName)
                .eq(VaccineAppointment::getAppointmentUserId,userId)
                .eq(myAppointmentDto.getState() != null,VaccineAppointment::getState,myAppointmentDto.getState());
        return baseMapper.selectJoinList(VaccineAppointmentVo.class,vaccineAppointmentMPJLambdaWrapper);
    }

    @Override
    public int verificationAppointment(VerificationAppointmentDTO verificationAppointmentDTO, Integer userId) {
        try {
            VaccineAppointment vaccineAppointment = JSONUtil.toBean(QRCodeUtil.decode(verificationAppointmentDTO.getAppointmentCode()), VaccineAppointment.class);
            Date now = new Date();
            if(vaccineAppointment.getAppointmentTime().before(now) && !"1".equals(vaccineAppointment.getState())){
                return 0;
            }
            vaccineAppointment.setState("3");
            return baseMapper.updateById(vaccineAppointment);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
